/*
| Sample codes are heavily modified for providing image acquisition
| class by Heesang Shin <shinheesang*at*gmail.com>
| Date: after 16th September, 2011
*********************************************************************************
* Copyleft (C) 2009 Md Omar Faruque Sarker <writefaruq*at*gmail.com>.
*
* Reproduction or disclosure of this file or its contents is granted without
* prior written consent of the Author.
*
*
* Program name: OpenCVCaptureProsilicaGigECamera.c
* Written by: Md Omar Faruque Sarker, PhD Student, Robotic Intelligence Lab,
*   University of Wales Newport
* Source Adapted from:  Metron Hong Kong Limited, a Prosilica camera Vendor
* Date: 31 March, 2008
* Version: 1.0
* Purpose: This example captures an image from a Prosilica GigE color camera and saves it
*			as a jpg file.
*
* Camera model: GE4900C
* Assumption: The image format is Bayer8
*
*********************************************************************************
*/
//#ifdef _WINDOWS

#include "stdafx.h"

//#endif

#include "VideoCapture_AvtGigE.h"

#include <colour_conv.h>

//#include <iostream>

#ifndef NO_AVT_GIGE

//int AvtGigE::OpenCVCaptureProsilicaGigECamera() {
//    initialised = capture_init();
//    std::cout<<"Camera ID = "<<myCamera.UID<<"\n";
//    //capture_image();
//    //// Display the image
//    //cvNamedWindow("Show image", 1);
//    //cvShowImage("Show image", rgbImage);
//    //// Wait for key input
//    //printf("\nPress any key to continue...\n");
//    //cvWaitKey();
//    // Save the image & release the images
//    //cvSaveImage("ImageColor.jpg", rgbImage);
//    // End capture
//    //capture_exit();
//    //OpenCV clean up
//    //cvReleaseImage(&bayerImage);
//    //cvReleaseImage(&rgbImage);
//   // cvDestroyWindow("Show image");
//	return 0;
//}

AvtGigE::AvtGigE()
{
    this->rawImage = NULL;
	this->initialised = false;
	this->width = 640;
	this->height = 480;
	this->verbose = true;
	this->myCamera.Frame.ImageBuffer = NULL;
	this->interacedCapture = false;
	//this->OpenCVCaptureProsilicaGigECamera();
}

AvtGigE::~AvtGigE()
{
	if(this->initialised) {
		this->closeCam();
	}
}

//int AvtGigE::countCameras()
//{
//	    // initialise the Prosilica API
//	Errcode = PvInitialize();
//    if(Errcode == ePvErrSuccess)
//    { 
//        // set the handler for CTRL-C
//        //SetConsoleCtrlHandler(CtrlCHandler, TRUE);
//        // the following call will only return upon CTRL-C
//		this->ListCameras();
//        // uninit the API
//        PvUnInitialize();
//    }
//    else {
//		this->processErrCode(Errcode);
//        std::cout<<"failed to initialise the API\n";
//	}
//	return 0;
//}

//void AvtGigE::ListCameras() {
//    tPvCameraInfo   cameraList[MAX_CAMERA_LIST];
//    unsigned long   cameraNum = 0;
//    unsigned long   cameraRle;
//	char buffer[999];
//	for(int i=0; i<10; i++) 
//	{
//        //sprintf_s(buffer,"***********************************\n");
//                std::cout<<"***********************************\n";
//        // first, get list of reachable cameras.
//        cameraNum = PvCameraList(cameraList,MAX_CAMERA_LIST,NULL);
//       // keep how many cameras listed are reachable
//        cameraRle = cameraNum;    
//        // then we append the list of unreachable cameras.
//        if (cameraNum < MAX_CAMERA_LIST)
//        {
//            cameraNum += PvCameraListUnreachable(&cameraList[cameraNum],
//                                                 MAX_CAMERA_LIST-cameraNum,
//                                                 NULL);
//        }
//        if(cameraNum)
//        {
//            struct in_addr addr;
//            tPvIpSettings Conf;
//            tPvErr lErr;
//            // and display them
//            for(unsigned long i=0;i<cameraNum;i++)
//            {
//                if(i < cameraRle)
//                {
//                    // get the camera's IP configuration
//                    if((lErr = PvCameraIpSettingsGet(cameraList[i].UniqueId,&Conf)) == ePvErrSuccess)
//                    {
//                        addr.s_addr = Conf.CurrentIpAddress;
//                        sprintf(buffer,"%s - %8s - Unique ID = % 8lu IP@ = %15s [%s]\n",cameraList[i].SerialString,
//                                                                    cameraList[i].DisplayName,
//                                                                    cameraList[i].UniqueId,
//                                                                    inet_ntoa(addr),
//                                                                    cameraList[i].PermittedAccess & ePvAccessMaster ? "available" : "in use");
//						std::cout<<buffer;
//                    }
//                    else {
//                        sprintf(buffer,"%s - %8s - Unique ID = % 8lu (unavailable, %u)\n",cameraList[i].SerialString,
//                               cameraList[i].DisplayName,
//                               cameraList[i].UniqueId,lErr);
//					std::cout<<buffer;
//					}
//                }
//                else {
//                    sprintf(buffer,"%s - %8s - Unique ID = % 8lu (*)\n",cameraList[i].SerialString,
//                                                              cameraList[i].DisplayName,
//                                                              cameraList[i].UniqueId);
//				std::cout<<buffer;
//				}
//            }
//
//            if(cameraNum != cameraRle) {
//                std::cout<<"(*) camera is not reachable\n";
//			}
//        }
//        else {
//            std::cout<<"No camera detected ...\n";
//		}
//        
//        fflush(stdout);
//        Sleep(1500);
//    }
//    printf("**************************************\n");
//}



#if defined(_LINUX) || defined(_QNX) || defined(_OSX)
void Sleep(unsigned int time)
{
    struct timespec t,r;
    
    t.tv_sec    = time / 1000;
    t.tv_nsec   = (time % 1000) * 1000000;    
    
    while(nanosleep(&t,&r)==-1)
        t = r;
}

void SetConsoleCtrlHandler(void (*func)(int), int junk)
{
  signal(SIGINT, func);
}
#endif

// CTRL-C handler
//#ifdef _WINDOWS
//BOOL WINAPI CtrlCHandler(DWORD dwCtrlType)
//#else
//void CtrlCHandler(int Signo)
//#endif
//{
//    gStop = true;     
//   
//    #ifndef _WINDOWS
//    signal(SIGINT, CtrlCHandler);
//    #else
//    return true;
//    #endif  
//}

//static

void AvtGigE::processErrCode(tPvErr errorCode) {
	if(this->verbose) {
		switch(errorCode) {
		case ePvErrBadHandle: std::cerr<<"the handle of the camera is invalid"<<"\n"; break;
		case ePvErrUnplugged: std::cerr<<"the camera has been unplugged"<<"\n"; break; 
		case ePvErrNotFound: std::cerr<<"the requested attribute doesn't exist"<<"\n"; break;
		case ePvErrWrongType: std::cerr<<"the requested attribute is not of the correct type"<<"\n"; break;
		case ePvErrForbidden: std::cerr<<"the requested attribute forbid this operation"<<"\n"; break;
		case ePvErrOutOfRange: std::cerr<<"the supplied value is out of range"<<"\n"; break;
		case ePvErrInternalFault: std::cerr<<"an internal fault occurred"<<"\n"; break;
		case ePvErrBadSequence: std::cerr<<"API isn't initialized"<<"\n"; break;
		case ePvErrTimeout: std::cerr<<"Timeout occurred before exposure completed."<<"\n"; break;
			//case ePvBadParameter: std::cerr<<"a valid pointer for pValue was not supplied"<<"\n"; break;

		default: std::cerr<<"Unknown error code : "<<errorCode<<"\n"; break;
		}
	}
}

int AvtGigE::probeCam(unsigned long manualIPaddress) {
	tPvErr Errcode = ePvErrSuccess;
	if(!this->initialised) Errcode = PvInitialize();
	if(Errcode == ePvErrSuccess){
		// Wait for the response from a camera after the initialization of the driver
		Sleep(300);
		unsigned long moreCamera = 0;
		unsigned long numCams = PvCameraListEx(this->cameraInfo, MAX_CAMERA_LIST, &moreCamera, sizeof(tPvCameraInfoEx));
		if(moreCamera>MAX_CAMERA_LIST) {
			if(this->verbose) std::cout<<"There are "<<moreCamera<<" cameras found, only up to "<<MAX_CAMERA_LIST<<" accessible, redefinable by MAX_CAMERA_LIST"<<"\n";
		}
		if(manualIPaddress != 0) {
			//unsigned long targetIp = manualIPaddress; //(130 << 24) | (123 << 16) | (248 << 8) | (16);
			unsigned long IpAddr = htonl(manualIPaddress);
			Errcode = PvCameraInfoByAddrEx(IpAddr,&this->cameraInfo[numCams],&this->ipSettings[numCams],sizeof(tPvCameraInfoEx));
			if(Errcode == ePvErrSuccess) {
				if(this->verbose) std::cout<<"Camera found by using manual IP search at ("<<manualIPaddress<<","<<IpAddr<<")"<<"\n";
				numCams++;
			} else {
				if(this->verbose) std::cout<<"Camera still not found by using manual IP search at ("<<manualIPaddress<<","<<IpAddr<<")"<<"\n";
			}
		}
		this->maxProbedCams = (unsigned int) numCams;
	}
	return (int) this->maxProbedCams;
}

bool AvtGigE::getCamId(int index, unsigned long &camId, std::string *camName) {
	if(!(index < this->maxProbedCams)) {
		if(this->verbose) std::cerr<<"Camera index out of bound\n";
		return false;
	}
	camId = this->cameraInfo[index].UniqueId;
	if(camName!=NULL) {
		camName->assign(std::string(this->cameraInfo[index].CameraName));
	}
	this->masterMode = this->cameraInfo[index].PermittedAccess == ePvAccessMaster ? true : false;
	return true;
}

bool AvtGigE::openCam(unsigned long camId) {
	if(this->initialised) {
		if(this->verbose) std::cout<<"AvtGigE is already initialised successfully."<<"\n";
		return true;
	}
	this->myCamera.UID = camId;
	if(this->verbose) std::cout<<"Camera ID ="<<myCamera.UID<<"\n";
	tPvErr Errcode;
	std::stringstream ss;
	// Open the camera
	if(this->masterMode) { 
		if(this->verbose) std::cout<<"the camera opening in master mode"<<"\n";
		Errcode = PvCameraOpen(this->myCamera.UID, ePvAccessMaster, &(this->myCamera.Handle));
	} else {
		std::cout<<"the camera opening in listen mode"<<"\n";
		Errcode = PvCameraOpen(this->myCamera.UID, ePvAccessMonitor, &(this->myCamera.Handle));
	}
	if(Errcode != ePvErrSuccess) {
		this->processErrCode(Errcode);
		if(this->verbose) {
			switch(Errcode) {
			case ePvErrAccessDenied:
				std::cerr<<"the camera couldn't be open in the requested mode"<<"\n";
				break;
			case ePvErrNotFound:
				std::cerr<<"the camera was not found (unplugged)"<<"\n";
				break;
			case ePvErrUnplugged:
				std::cerr<<"the camera was found but unplugged during the function call"<<"\n";
				break;
			case ePvErrBadParameter:
				std::cerr<<"a valid pointer for pCamera was not supplied"<<"\n";
				break;
			case ePvErrResources:
				std::cerr<<"resources requested from the OS were not available"<<"\n";
				break;
			case ePvErrInternalFault:
				std::cerr<<"an internal fault occurred"<<"\n";
				break;
			case ePvErrBadSequence:
				std::cerr<<"API isn't initialized or camera is alreay open"<<"\n";
				break;
			}
			std::cout<<"open camera error\n";
		}
		return false;
	}
	if(this->masterMode) PvAttrUint32Set(this->myCamera.Handle, "Width", this->width);// else PvAttrUint32Get(this->myCamera.Handle, "Width", &this->width);
	if(this->masterMode) PvAttrUint32Set(this->myCamera.Handle, "Height", this->height);// else PvAttrUint32Get(this->myCamera.Handle, "Height", &this->height);
	// Get the image size of every capture
	Errcode = PvAttrUint32Get(this->myCamera.Handle, "TotalBytesPerFrame", &this->frameSize);
	if (Errcode != ePvErrSuccess) 
	{
		this->processErrCode(Errcode);
		if(this->verbose) std::cerr<<"Errcode: "<<Errcode<<"Could not open video source: \n";
	}
	if(this->verbose) std::cout<<"Frame size = "<<frameSize<<"\n";//%ld\n", frameSize);
	// Allocate a buffer to store the image
	memset(&this->myCamera.Frame, 0, sizeof(tPvFrame));
	this->myCamera.Frame.ImageBufferSize = this->frameSize;
	this->myCamera.Frame.ImageBuffer = cvAlloc(this->frameSize);
	// Get the width & height of the image
	PvAttrUint32Get(this->myCamera.Handle, "Width", &width);
	PvAttrUint32Get(this->myCamera.Handle, "Height", &height);
	if(this->verbose) {
		ss<<"Frame width = "<<this->width<<"\n";
		ss<<"Frame height = "<<this->height<<"\n";
		std::cout<<ss.str();
		ss.clear();
	}
	// Start the camera
	PvCaptureStart(this->myCamera.Handle);
	// Set the camera to capture continuously
	if(this->masterMode) {
		Errcode = PvAttrEnumSet(this->myCamera.Handle, "AcquisitionMode", "Continuous");
		if (Errcode != ePvErrSuccess) {
			this->processErrCode(Errcode);
			if(this->verbose) std::cerr<<"Could not set AcquisitionMode. Error Code:"<<Errcode<<"\n";
		}
	} else {
		char textBuffer[999];
		int textBufferN = strlen(textBuffer);
		Errcode = PvAttrEnumGet(this->myCamera.Handle, "AcquisitionMode", textBuffer,textBufferN,NULL);
		if (Errcode != ePvErrSuccess) {
			this->processErrCode(Errcode);
			if(this->verbose) std::cerr<<"Acquisition Mode listen failed."<<"\n";
		} else {
			if(this->verbose) std::cout<<"Acquisition Mode as "<<textBuffer<<"\n";
		}
	}
	if(this->verbose) std::cout<<"start the acquisition\n";
	Errcode = PvCommandRun(this->myCamera.Handle, "AcquisitionStart");
	if (Errcode != ePvErrSuccess) {
		this->processErrCode(Errcode);
		if(this->verbose) std::cerr<<" Could not run AcquisitionStart command. Errcode:"<<Errcode<<"\n";
	}
	if(this->masterMode) {
		Errcode = PvAttrEnumSet(this->myCamera.Handle, "FrameStartTriggerMode", "Freerun");
		if (Errcode != ePvErrSuccess) {
			this->processErrCode(Errcode);
			if(this->verbose) std::cerr<<" Could not set FrameStartTriggerMode. Errcode:"<<Errcode<<"\n";
		}
	} else {
		char textBuffer[999];
		int textBufferN = strlen(textBuffer);
		Errcode = PvAttrEnumGet(this->myCamera.Handle, "FrameStartTriggerMode", textBuffer,textBufferN,NULL);
		if (Errcode != ePvErrSuccess) {
			this->processErrCode(Errcode);
			if(this->verbose) std::cerr<<"FrameStartTriggerMode Mode listen failed."<<"\n";
		} else {
			if(this->verbose) std::cout<<"FrameStartTriggerMode Mode as "<<textBuffer<<"\n";
		}
	}
	rawImage = cvCreateImageHeader(cvSize((int)width, (int)height), IPL_DEPTH_8U, CH_MONO);
	rawImage->widthStep = (int)width;
	rawImage->imageData = (char *)myCamera.Frame.ImageBuffer;	// Points the image to the buffer of the camera
	// Create an image (24 bits RGB Color image)
	//rgbImage = cvCreateImage(cvSize((int)width, (int)height), IPL_DEPTH_8U, CH_COLOR);
	//rgbImage->widthStep = (int)width * CH_COLOR;
	initialised = true;
	return true;
}

bool AvtGigE::getCamProperties(char *propId, unsigned long &value) {
	tPvErr			Errcode;
	tPvUint32 convertedValue;
	Errcode = PvAttrUint32Get(this->myCamera.Handle, propId, &convertedValue);
	value = (unsigned long) convertedValue;
	if(Errcode != ePvErrSuccess) return false;
	return true;
}

bool AvtGigE::setCamProperties(char *propId, unsigned long value) {
	tPvErr			Errcode;
	tPvUint32 convertedValue = (tPvUint32) value;
	Errcode = PvAttrUint32Set(this->myCamera.Handle, propId, (tPvUint32) &convertedValue);
	if(Errcode != ePvErrSuccess) return false;
	return true;
}

bool AvtGigE::setImageSize(unsigned int width, unsigned int height, unsigned int bytesPerChannel, unsigned int channels) {
	this->width = (tPvUint32) width;
	this->height = (tPvUint32) height;
	return true;
}


//bool AvtGigE::capture_init(tPvUint32 widthParam, tPvUint32 heightParam)
//{
//	if(initialised) {
//		std::cout<<"AvtGigE is already initialised successfully."<<"\n";
//		return initialised;
//	}
//	char textBuffer[999];
//	Errcode = PvInitialize();
//	if(Errcode == ePvErrSuccess){
//		// Wait for the response from a camera after the initialization of the driver
//		Sleep(300);
//		unsigned long moreCamera = 0;
//		unsigned long numCams = PvCameraListEx(cameraInfo, MAX_CAMERA_LIST, &moreCamera, sizeof(tPvCameraInfoEx));
//		if(moreCamera>MAX_CAMERA_LIST) {
//			std::cout<<"There are "<<moreCamera<<" cameras found, only up to "<<MAX_CAMERA_LIST<<" accessible, redefinable by MAX_CAMERA_LIST"<<"\n";
//		}
//		if(numCams < 1 ) {
//			unsigned long targetIp = (130 << 24) | (123 << 16) | (248 << 8) | (16);
//			unsigned long IpAddr = htonl(targetIp);
//			Errcode = PvCameraInfoByAddrEx(IpAddr,&cameraInfo[0],&ipSettings[0],sizeof(tPvCameraInfoEx));
//			if(Errcode == ePvErrSuccess) {
//				std::cout<<"Camera found by using manual IP search at ("<<targetIp<<","<<IpAddr<<")"<<"\n";
//				numCams = 1;
//			} else {
//				std::cout<<"Camera still not found by using manual IP search at ("<<targetIp<<","<<IpAddr<<")"<<"\n";
//			}
//		}
//		if (numCams > 0)
//		{
//			int selectedCamera = 0;
//			bool masterMode = true;
//			std::cout<<"Camera #0 is selected."<<"\n";
//			// Get the camera ID
//			myCamera.UID = cameraInfo[selectedCamera].UniqueId;
//			std::cout<<"Camera ID ="<<myCamera.UID<<"\n";
//			// Open the camera
//			if(true) { //cameraInfo[selectedCamera].PermittedAccess == ePvAccessMaster) {
//				std::cout<<"the camera opening in master mode"<<"\n";
//				Errcode = PvCameraOpen(myCamera.UID, ePvAccessMaster, &(myCamera.Handle));
//			} else {
//				std::cout<<"the camera opening in listen mode"<<"\n";
//				Errcode = PvCameraOpen(myCamera.UID, ePvAccessMonitor, &(myCamera.Handle));
//				masterMode = false;
//			}
//			if(Errcode == ePvErrSuccess)
//			{
//				if(masterMode) PvAttrUint32Set(myCamera.Handle, "Width", widthParam);
//				if(masterMode) PvAttrUint32Set(myCamera.Handle, "Height", heightParam);
//				// Get the image size of every capture
//				Errcode = PvAttrUint32Get(myCamera.Handle, "TotalBytesPerFrame", &frameSize);
//				if (Errcode != ePvErrSuccess) 
//				{
//					this->processErrCode(Errcode);
//					sprintf(textBuffer, "Errcode: %d Could not open video source: \n", Errcode);
//					std::cerr<<textBuffer;
//				}
//				std::cout<<"Frame size = "<<frameSize<<"\n";//%ld\n", frameSize);
//				// Allocate a buffer to store the image
//				memset(&myCamera.Frame, 0, sizeof(tPvFrame));
//				myCamera.Frame.ImageBufferSize = frameSize;
//				myCamera.Frame.ImageBuffer = cvAlloc(frameSize);
//				// Get the width & height of the image
//				PvAttrUint32Get(myCamera.Handle, "Width", &width);
//				PvAttrUint32Get(myCamera.Handle, "Height", &height);
//				sprintf(textBuffer,"Frame width \t\t= %ld\n", width);
//				std::cout<<textBuffer;
//				sprintf(textBuffer,"Frame height \t\t= %ld\n\n", height);
//				std::cout<<textBuffer;
//				// Start the camera
//				PvCaptureStart(myCamera.Handle);
//				// Set the camera to capture continuously
//				if(masterMode) {
//					Errcode = PvAttrEnumSet(myCamera.Handle, "AcquisitionMode", "Continuous");
//					if (Errcode != ePvErrSuccess) {
//						this->processErrCode(Errcode);
//						sprintf(textBuffer, "Errcode: %d Could not set AcquisitionMode.\n", Errcode);
//						std::cerr<<textBuffer;
//					}
//				} else {
//					Errcode = PvAttrEnumGet(myCamera.Handle, "AcquisitionMode", textBuffer,999,NULL);
//					if (Errcode != ePvErrSuccess) {
//						this->processErrCode(Errcode);
//						std::cerr<<"Acquisition Mode listen failed."<<"\n";
//					} else {
//						std::cout<<"Acquisition Mode as "<<textBuffer<<"\n";
//					}
//				}
//				std::cout<<"start the acquisition\n";
//				Errcode = PvCommandRun(myCamera.Handle, "AcquisitionStart");
//				if (Errcode != ePvErrSuccess) {
//					this->processErrCode(Errcode);
//					sprintf(textBuffer, "Errcode: %d Could not run AcquisitionStart command.\n", Errcode);
//					std::cerr<<textBuffer;
//				}
//				if(masterMode) {
//					Errcode = PvAttrEnumSet(myCamera.Handle, "FrameStartTriggerMode", "Freerun");
//					if (Errcode != ePvErrSuccess) {
//						this->processErrCode(Errcode);
//						sprintf(textBuffer, "Errcode: %d Could not set FrameStartTriggerMode.\n", Errcode);
//						std::cerr<<textBuffer;
//					}
//				} else {
//					Errcode = PvAttrEnumGet(myCamera.Handle, "FrameStartTriggerMode", textBuffer,999,NULL);
//					if (Errcode != ePvErrSuccess) {
//						this->processErrCode(Errcode);
//						std::cerr<<"FrameStartTriggerMode Mode listen failed."<<"\n";
//					} else {
//						std::cout<<"FrameStartTriggerMode Mode as "<<textBuffer<<"\n";
//					}
//				}
//				rawImage = cvCreateImageHeader(cvSize((int)width, (int)height), IPL_DEPTH_8U, CH_MONO);
//				rawImage->widthStep = (int)width;
//				rawImage->imageData = (char *)myCamera.Frame.ImageBuffer;	// Points the image to the buffer of the camera
//				// Create an image (24 bits RGB Color image)
//				rgbImage = cvCreateImage(cvSize((int)width, (int)height), IPL_DEPTH_8U, CH_COLOR);
//				//rgbImage->widthStep = (int)width * CH_COLOR;
//				initialised = true;
//				return true;
//			}
//			else
//			{
//				this->processErrCode(Errcode);
//				switch(Errcode) {
//				case ePvErrAccessDenied:
//					std::cerr<<"the camera couldn't be open in the requested mode"<<"\n";
//					break;
//				case ePvErrNotFound:
//					std::cerr<<"the camera was not found (unplugged)"<<"\n";
//					break;
//				case ePvErrUnplugged:
//					std::cerr<<"the camera was found but unplugged during the function call"<<"\n";
//					break;
//				case ePvErrBadParameter:
//					std::cerr<<"a valid pointer for pCamera was not supplied"<<"\n";
//					break;
//				case ePvErrResources:
//					std::cerr<<"resources requested from the OS were not available"<<"\n";
//					break;
//				case ePvErrInternalFault:
//					std::cerr<<"an internal fault occurred"<<"\n";
//					break;
//				case ePvErrBadSequence:
//					std::cerr<<"API isn't initialized or camera is alreay open"<<"\n";
//					break;
//				}
//				std::cout<<"open camera error\n";
//				return false;
//			}
//		}
//		else {
//			std::cout<<"camera not found\n";
//			return false;
//		}
//	}
//	else {
//		switch(Errcode) {
//		case ePvErrResources:
//			std::cerr<<"resources requested from the OS were not available"<<"\n";
//			break;
//		case ePvErrInternalFault:
//			std::cerr<<"an internal fault occurred"<<"\n";
//			break;
//		}
//		std::cout<<"failed to initialise the API\n";
//		return false;
//	}
//}

IplImage*  AvtGigE::grabRawImage() {
	tPvErr Errcode = PvCaptureQueueFrame(this->myCamera.Handle, &this->myCamera.Frame, NULL);
    if(Errcode == ePvErrSuccess){
			Errcode = PvCaptureWaitForFrameDone(this->myCamera.Handle, &this->myCamera.Frame, 1000); // == ePvErrTimeout);
			if(Errcode == ePvErrSuccess){
	        rawImage->imageData = (char *)this->myCamera.Frame.ImageBuffer;	// Points the image to the buffer of the camera
        // Create an image (24 bits RGB Color image)
  //      rgbImage = cvCreateImage(cvSize((int)width, (int)height), IPL_DEPTH_8U, CH_COLOR);
 //       rgbImage->widthStep = (int)width * CH_COLOR;
        // Convert the bayer image to the RGB image RG2RGB, BG2BGR
//                cvCvtColor(rawImage, rgbImage,  CV_BayerBG2BGR); //CV_BayerBG2BGR); CV_BayerBG2BGR_VNG
		//demosaicingNaked(bayerImage->imageData, rgbImage->imageData, rgbImage->width, rgbImage->height, bayerImage->widthStep, rgbImage->widthStep);
			} else {
				this->processErrCode(Errcode);
			}
    } else {
		this->processErrCode(Errcode);
		if(this->verbose) std::cout<<"prosilica_raw_capture(): failed to capture\n";
    }
	return rawImage;
}

bool AvtGigE::closeCam(){
	if(!this->initialised) return false;
	tPvErr Errcode;
	Errcode = PvCommandRun(myCamera.Handle, "AcquisitionStop");
  if (Errcode != ePvErrSuccess) {
	  this->processErrCode(Errcode);
	  if(this->verbose) std::cerr<<"Errcode: "<<Errcode<<" Could not open video source: \n";
  }
	PvCaptureEnd(this->myCamera.Handle);
	PvCameraClose(this->myCamera.Handle);
	PvUnInitialize();
	if(this->rawImage!=NULL) cvReleaseImage(&this->rawImage);
	this->rawImage = NULL;
	if(this->myCamera.Frame.ImageBuffer!=NULL) cvFree(&this->myCamera.Frame.ImageBuffer);
	this->myCamera.Frame.ImageBuffer = NULL;
  initialised = false;
  if(this->verbose) std::cout<<"Capture finished\n.";
  return true;
}

#endif
